import paramiko
import configparser
import sys
import getpass
import os

def encodePassword(password, key):
	result = ''
	for char in password:
		result += chr(ord(char) ^ key)
	return result

def decodePassword(password, key):
	return encodePassword(password, key)

def setUserInfo():
	username = input("username:")
	password = getpass.getpass('password:')
	config = configparser.RawConfigParser()
	config.add_section('userInfo')
	config.set('userInfo', 'username', username)
	config.set('userInfo', 'password', encodePassword(password, 0x22))
	with open('./ssh.cfg', 'w') as f:
		config.write(f)

def getUserInfo():
	config = configparser.RawConfigParser()
	config.read('./ssh.cfg')
	username = config.get("userInfo", "username")
	password = decodePassword(config.get("userInfo", "password"), 0x22)
	return username, password

def gethostInfo():
	config = configparser.RawConfigParser()
	config.read('./ssh.cfg')
	hostIP = config.get("hostInfo", "hostIP")
	hostPort = config.get("hostInfo", "hostPort")
	return hostIP, hostPort

def getSyncPath():
	config = configparser.RawConfigParser()
	config.read('./ssh.cfg')
	localPath = config.get("hostInfo", "localPath")
	hostPath = config.get("hostInfo", "hostPath")
	return localPath, hostPath

def getScriptInfo():
	config = configparser.RawConfigParser()
	config.read('./ssh.cfg')
	scriptFilePath = config.get("scriptInfo", "scriptFile")
	return scriptFilePath

def checkHostPath(ssh, hostFilePath):
	hostDirPath = os.path.dirname(hostFilePath)
	cmd = 'cd ' + hostDirPath
	stdin, stdout, stderr = ssh.exec_command(cmd)
	result = stdout.read()
	if not result:
		if len(stderr.read()) > 0:
			cmd = 'mkdir ' + hostDirPath
			stdin, stdout, stderr = ssh.exec_command(cmd)
			result = stdout.read()
			if not result:
				if len(stderr.read()) > 0:
					print("远程服务器无法创建目录" + hostDirPath)
					ssh.close()
					return False
	return True

def updateLocalFiles(ssh, hostIP, hostPort, username, password, localPath, hostPath):
	if (localPath[-1] == '/') or (localPath[-1] == '\\'):
		localPath = localPath[ : len(localPath) - 1]
	if (hostPath[-1] == '/') or (hostPath[-1] == '\\'):
		hostPath = hostPath[ : len(hostPath) - 1]	
	for root, dirs, files in os.walk(localPath):
		for file in files:
			localFilePath = os.path.join(root,file).replace('\\', '/')
			hostFilePath = hostPath + localFilePath.replace(localPath, '')
			transport = paramiko.Transport((hostIP, int(hostPort)))
			transport.connect(username = username, password = password)
			sftp = paramiko.SFTPClient.from_transport(transport)
			if checkHostPath(ssh, hostFilePath) == False:
				exit(0)
			sftp.put(localFilePath, hostFilePath)

def executeScriptFile(ssh, scriptFilePath):
	with open(scriptFilePath, 'r') as f:
		while True:
			cmd = f.readline()
			if not cmd:
				break
			print('>>>' + cmd)
			stdin, stdout, stderr = ssh.exec_command(cmd, get_pty = True)
			result = stdout.read()
			if not result:
				result = stderr.read()
			print('>>>' + result.decode())
	ssh.close()

def executeScript():
	username, password = getUserInfo()
	hostIP, hostPort = gethostInfo()
	scriptFilePath = getScriptInfo()
	ssh = paramiko.SSHClient()
	ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
	try:
		ssh.connect(hostname = hostIP, port = hostPort, username = username, password = password)
	except TimeoutError as e:
		print("连接超时，无法连接至远程主机")
		exit(0)
	localPath, hostPath = getSyncPath()
	updateLocalFiles(ssh, hostIP, hostPort, username, password, localPath, hostPath)
	executeScriptFile(ssh, scriptFilePath)


if __name__ == '__main__':
	argv = sys.argv
	if(len(argv) > 1):
		if argv[1] == '-s':
			setUserInfo()
	else:
		executeScript()

'''
#创建SSH对象
ssh = paramiko.SSHClient()

#把要连接的机器添加到known_hosts文件中
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())

#连接服务器
ssh.connect(hostname=hostip, port=hostport, username='wwx', password='wwx1219484671')

cmd = 'ifconfig'
stdin, stdout, stderr = ssh.exec_command(cmd)

result = stdout.read()

if not result:
    result = stderr.read()
ssh.close()

print(result.decode())





config = configparser.RawConfigParser()
config.add_section('userInfo')
config.set('userInfo', 'username', 'wwx')
with open('./ssh.cfg', 'w') as f:
	config.write(f)


transport = paramiko.Transport((hostip, hostport))

transport.connect(username='wwx', password='wwx1219484671')

sftp = paramiko.SFTPClient.from_transport(transport)
sftp.put('./test.txt', '/home/wwx/Desktop/test.txt')
'''